'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const axios_1 = require('axios');
const cheerio_1 = require('cheerio');
const CryptoJS = require('crypto-js');
const dayjs = require('dayjs');
const pageSize = 20;
const headers = {
	'user-agent':
		'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36',
};
function nonce(e = 10) {
	let n = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
		r = '';
	for (let i = 0; i < e; i++)
		r += n.charAt(Math.floor(Math.random() * n.length));
	return r;
}
function getNormalizedParams(parameters) {
	const sortedKeys = [];
	const normalizedParameters = [];
	for (let e in parameters) {
		sortedKeys.push(_encode(e));
	}
	sortedKeys.sort();
	for (let idx = 0; idx < sortedKeys.length; idx++) {
		const e = sortedKeys[idx];
		var n,
			r,
			i = _decode(e),
			a = parameters[i];
		for (a.sort(), n = 0; n < a.length; n++)
			(r = _encode(a[n])), normalizedParameters.push(e + '=' + r);
	}
	return normalizedParameters.join('&');
}
function _encode(e) {
	return e
		? encodeURIComponent(e)
				.replace(/[!'()]/g, escape)
				.replace(/\*/g, '%2A')
		: '';
}
function _decode(e) {
	return e ? decodeURIComponent(e) : '';
}
function u(e) {
	(this._parameters = {}), this._loadParameters(e || {});
}
u.prototype = {
	_loadParameters: function (e) {
		e instanceof Array
			? this._loadParametersFromArray(e)
			: 'object' == typeof e && this._loadParametersFromObject(e);
	},
	_loadParametersFromArray: function (e) {
		var n;
		for (n = 0; n < e.length; n++) this._loadParametersFromObject(e[n]);
	},
	_loadParametersFromObject: function (e) {
		var n;
		for (n in e)
			if (e.hasOwnProperty(n)) {
				var r = this._getStringFromParameter(e[n]);
				this._loadParameterValue(n, r);
			}
	},
	_loadParameterValue: function (e, n) {
		var r;
		if (n instanceof Array) {
			for (r = 0; r < n.length; r++) {
				var i = this._getStringFromParameter(n[r]);
				this._addParameter(e, i);
			}
			0 == n.length && this._addParameter(e, '');
		} else this._addParameter(e, n);
	},
	_getStringFromParameter: function (e) {
		var n = e || '';
		try {
			('number' == typeof e || 'boolean' == typeof e) && (n = e.toString());
		} catch (e) {}
		return n;
	},
	_addParameter: function (e, n) {
		this._parameters[e] || (this._parameters[e] = []),
			this._parameters[e].push(n);
	},
	get: function () {
		return this._parameters;
	},
};
function getSignature(
	method,
	urlPath,
	params,
	secret = 'f3ac5b086f3eab260520d8e3049561e6'
) {
	urlPath = urlPath.split('?')[0];
	urlPath = urlPath.startsWith('http')
		? urlPath
		: 'https://api.audiomack.com/v1' + urlPath;
	const r = new u(params).get();
	const httpMethod = method.toUpperCase();
	const normdParams = getNormalizedParams(r);
	const l =
		_encode(httpMethod) + '&' + _encode(urlPath) + '&' + _encode(normdParams);
	const hash = CryptoJS.HmacSHA1(l, secret + '&').toString(CryptoJS.enc.Base64);
	return hash;
}
function formatMusicItem(raw) {
	return {
		id: raw.id,
		artwork: raw.image || raw.image_base,
		duration: +raw.duration,
		title: raw.title,
		artist: raw.artist,
		album: raw.album,
		url_slug: raw.url_slug,
	};
}
function formatAlbumItem(raw) {
	var _a, _b;
	return {
		artist: raw.artist,
		artwork: raw.image || raw.image_base,
		id: raw.id,
		date: dayjs.unix(+raw.released).format('YYYY-MM-DD'),
		title: raw.title,
		_musicList:
			(_b =
				(_a = raw === null || raw === void 0 ? void 0 : raw.tracks) === null ||
				_a === void 0
					? void 0
					: _a.map) === null || _b === void 0
				? void 0
				: _b.call(_a, it => ({
						id: it.song_id || it.id,
						artwork: raw.image || raw.image_base,
						duration: +it.duration,
						title: it.title,
						artist: it.artist,
						album: raw.title,
				  })),
	};
}
function formatMusicSheetItem(raw) {
	var _a, _b, _c, _d, _e, _f;
	return {
		worksNum: raw.track_count,
		id: raw.id,
		title: raw.title,
		artist: (_a = raw.artist) === null || _a === void 0 ? void 0 : _a.name,
		artwork: raw.image || raw.image_base,
		artistItem: {
			id: (_b = raw.artist) === null || _b === void 0 ? void 0 : _b.id,
			avatar:
				((_c = raw.artist) === null || _c === void 0 ? void 0 : _c.image) ||
				((_d = raw.artist) === null || _d === void 0 ? void 0 : _d.image_base),
			name: (_e = raw.artist) === null || _e === void 0 ? void 0 : _e.name,
			url_slug:
				(_f = raw.artist) === null || _f === void 0 ? void 0 : _f.url_slug,
		},
		createAt: dayjs.unix(+raw.created).format('YYYY-MM-DD'),
		url_slug: raw.url_slug,
	};
}
async function searchBase(query, page, show) {
	const params = {
		limit: pageSize,
		oauth_consumer_key: 'audiomack-js',
		oauth_nonce: nonce(32),
		oauth_signature_method: 'HMAC-SHA1',
		oauth_timestamp: Math.round(Date.now() / 1e3),
		oauth_version: '1.0',
		page: page,
		q: query,
		show: show,
		sort: 'popular',
	};
	const oauth_signature = getSignature('GET', '/search', params);
	const results = (
		await axios_1.default.get('https://api.audiomack.com/v1/search', {
			headers,
			params: Object.assign(Object.assign({}, params), { oauth_signature }),
		})
	).data.results;
	return results;
}
async function searchMusic(query, page) {
	const results = await searchBase(query, page, 'songs');
	return {
		isEnd: results.length < pageSize,
		data: results.map(formatMusicItem),
	};
}
async function searchAlbum(query, page) {
	const results = await searchBase(query, page, 'albums');
	return {
		isEnd: results.length < pageSize,
		data: results.map(formatAlbumItem),
	};
}
async function searchMusicSheet(query, page) {
	const results = await searchBase(query, page, 'playlists');
	return {
		isEnd: results.length < pageSize,
		data: results.map(formatMusicSheetItem),
	};
}
async function searchArtist(query, page) {
	const results = await searchBase(query, page, 'artists');
	return {
		isEnd: results.length < pageSize,
		data: results.map(raw => ({
			name: raw.name,
			id: raw.id,
			avatar: raw.image || raw.image_base,
			url_slug: raw.url_slug,
		})),
	};
}
let dataUrlBase;
async function getDataUrlBase() {
	if (dataUrlBase) {
		return dataUrlBase;
	}
	const rawHtml = (await axios_1.default.get('https://audiomack.com/')).data;
	const $ = (0, cheerio_1.load)(rawHtml);
	const script = $('script#__NEXT_DATA__').text();
	const jsonObj = JSON.parse(script);
	if (jsonObj.buildId) {
		dataUrlBase = `https://audiomack.com/_next/data/${jsonObj.buildId}`;
	}
	return dataUrlBase;
}
async function getArtistWorks(artistItem, page, type) {
	if (type === 'music') {
		const params = {
			artist_id: artistItem.id,
			limit: pageSize,
			oauth_consumer_key: 'audiomack-js',
			oauth_nonce: nonce(32),
			oauth_signature_method: 'HMAC-SHA1',
			oauth_timestamp: Math.round(Date.now() / 1e3),
			oauth_version: '1.0',
			page: page,
			sort: 'rank',
			type: 'songs',
		};
		const oauth_signature = getSignature(
			'GET',
			'/search_artist_content',
			params
		);
		const results = (
			await axios_1.default.get(
				'https://api.audiomack.com/v1/search_artist_content',
				{
					headers,
					params: Object.assign(Object.assign({}, params), { oauth_signature }),
				}
			)
		).data.results;
		return {
			isEnd: results.length < pageSize,
			data: results.map(formatMusicItem),
		};
	} else if (type === 'album') {
		const params = {
			artist_id: artistItem.id,
			limit: pageSize,
			oauth_consumer_key: 'audiomack-js',
			oauth_nonce: nonce(32),
			oauth_signature_method: 'HMAC-SHA1',
			oauth_timestamp: Math.round(Date.now() / 1e3),
			oauth_version: '1.0',
			page: page,
			sort: 'rank',
			type: 'albums',
		};
		const oauth_signature = getSignature(
			'GET',
			'/search_artist_content',
			params
		);
		const results = (
			await axios_1.default.get(
				'https://api.audiomack.com/v1/search_artist_content',
				{
					headers,
					params: Object.assign(Object.assign({}, params), { oauth_signature }),
				}
			)
		).data.results;
		return {
			isEnd: results.length < pageSize,
			data: results.map(formatAlbumItem),
		};
	}
}
async function getMusicSheetInfo(sheet, page) {
	const _dataUrlBase = await getDataUrlBase();
	const res = (
		await axios_1.default.get(
			`${_dataUrlBase}/${sheet.artistItem.url_slug}/playlist/${sheet.url_slug}.json`,
			{
				params: {
					page_slug: sheet.artistItem.url_slug,
					playlist_slug: sheet.url_slug,
				},
				headers: Object.assign({}, headers),
			}
		)
	).data;
	const musicPage = res.pageProps.initialState.musicPage;
	const targetKey = Object.keys(musicPage).find(it =>
		it.startsWith('musicMusicPage')
	);
	const tracks = musicPage[targetKey].results.tracks;
	return {
		isEnd: true,
		musicList: tracks.map(formatMusicItem),
	};
}
async function getMediaSource(musicItem, quality) {
	if (quality !== 'standard') {
		return;
	}
	const params = {
		environment: 'desktop-web',
		hq: true,
		oauth_consumer_key: 'audiomack-js',
		oauth_nonce: nonce(32),
		oauth_signature_method: 'HMAC-SHA1',
		oauth_timestamp: Math.round(Date.now() / 1e3),
		oauth_version: '1.0',
		section: '/search',
	};
	const oauth_signature = getSignature(
		'GET',
		`/music/play/${musicItem.id}`,
		params
	);
	const res = (
		await axios_1.default.get(
			`https://api.audiomack.com/v1/music/play/${musicItem.id}`,
			{
				headers: Object.assign(Object.assign({}, headers), {
					origin: 'https://audiomack.com',
				}),
				params: Object.assign(Object.assign({}, params), { oauth_signature }),
			}
		)
	).data;
	return {
		url: res.signedUrl,
	};
}
async function getAlbumInfo(albumItem) {
	return {
		musicList: albumItem._musicList.map(it => Object.assign({}, it)),
	};
}
async function getRecommendSheetTags() {
	const rawHtml = (await axios_1.default.get('https://audiomack.com/playlists'))
		.data;
	const $ = (0, cheerio_1.load)(rawHtml);
	const script = $('script#__NEXT_DATA__').text();
	const jsonObj = JSON.parse(script);
	return {
		data: [
			{
				data: jsonObj.props.pageProps.categories,
			},
		],
	};
}
async function getRecommendSheetsByTag(tag, page) {
	if (!tag.id) {
		tag = { id: '34', title: "What's New", url_slug: 'whats-new' };
	}
	const params = {
		featured: 'yes',
		limit: pageSize,
		oauth_consumer_key: 'audiomack-js',
		oauth_nonce: nonce(32),
		oauth_signature_method: 'HMAC-SHA1',
		oauth_timestamp: Math.round(Date.now() / 1e3),
		oauth_version: '1.0',
		page: page,
		slug: tag.url_slug,
	};
	const oauth_signature = getSignature('GET', '/playlist/categories', params);
	const results = (
		await axios_1.default.get(
			'https://api.audiomack.com/v1/playlist/categories',
			{
				headers,
				params: Object.assign(Object.assign({}, params), { oauth_signature }),
			}
		)
	).data.results.playlists;
	return {
		isEnd: results.length < pageSize,
		data: results.map(formatMusicSheetItem),
	};
}
async function getTopLists() {
	const genres = [
		{
			title: 'All Genres',
			url_slug: null,
		},
		{
			title: 'Afrosounds',
			url_slug: 'afrobeats',
		},
		{
			title: 'Hip-Hop/Rap',
			url_slug: 'rap',
		},
		{
			title: 'Latin',
			url_slug: 'latin',
		},
		{
			title: 'Caribbean',
			url_slug: 'caribbean',
		},
		{
			title: 'Pop',
			url_slug: 'pop',
		},
		{
			title: 'R&B',
			url_slug: 'rb',
		},
		{
			title: 'Gospel',
			url_slug: 'gospel',
		},
		{
			title: 'Electronic',
			url_slug: 'electronic',
		},
		{
			title: 'Rock',
			url_slug: 'rock',
		},
		{
			title: 'Punjabi',
			url_slug: 'punjabi',
		},
		{
			title: 'Country',
			url_slug: 'country',
		},
		{
			title: 'Instrumental',
			url_slug: 'instrumental',
		},
		{
			title: 'Podcast',
			url_slug: 'podcast',
		},
	];
	return [
		{
			title: 'Trending Songs',
			data: genres.map(it => {
				var _a;
				return Object.assign(Object.assign({}, it), {
					type: 'trending',
					id: (_a = it.url_slug) !== null && _a !== void 0 ? _a : it.title,
				});
			}),
		},
		{
			title: 'Recently Added Music',
			data: genres.map(it => {
				var _a;
				return Object.assign(Object.assign({}, it), {
					type: 'recent',
					id: (_a = it.url_slug) !== null && _a !== void 0 ? _a : it.title,
				});
			}),
		},
	];
}
async function getTopListDetail(topListItem, page = 1) {
	const type = topListItem.type;
	const partialUrl = `/music/${
		topListItem.url_slug ? `${topListItem.url_slug}/` : ''
	}${type}/page/${page}`;
	const url = `https://api.audiomack.com/v1${partialUrl}`;
	const params = {
		oauth_consumer_key: 'audiomack-js',
		oauth_nonce: nonce(32),
		oauth_signature_method: 'HMAC-SHA1',
		oauth_timestamp: Math.round(Date.now() / 1e3),
		oauth_version: '1.0',
		type: 'song',
	};
	const oauth_signature = getSignature('GET', partialUrl, params);
	const results = (
		await axios_1.default.get(url, {
			headers,
			params: Object.assign(Object.assign({}, params), { oauth_signature }),
		})
	).data.results;
	return {
		musicList: results.map(formatMusicItem),
	};
}
module.exports = {
	platform: 'Audiomack',
	version: '0.0.2',
	author: '猫头猫',
	primaryKey: ['id', 'url_slug'],
	srcUrl:
		'https://gitee.com/zychhf/ftp2/raw/master/music-free/audiomack/index.js',
	cacheControl: 'no-cache',
	supportedSearchType: ['music', 'album', 'sheet', 'artist'],
	async search(query, page, type) {
		if (type === 'music') {
			return await searchMusic(query, page);
		} else if (type === 'album') {
			return await searchAlbum(query, page);
		} else if (type === 'sheet') {
			return await searchMusicSheet(query, page);
		} else if (type === 'artist') {
			return await searchArtist(query, page);
		}
	},
	getMediaSource,
	getAlbumInfo,
	getMusicSheetInfo,
	getArtistWorks,
	getRecommendSheetTags,
	getRecommendSheetsByTag,
	getTopLists,
	getTopListDetail,
};
